home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMICUS26.ADF / SoundScape / LatticeExamples / echo.c < prev    next >
C/C++ Source or Header  |  1989-01-26  |  7KB  |  361 lines

  1. /*    Echo.c
  2.  
  3.     (c) 1987    Todor Fay
  4.  
  5.     Lattice version
  6.  
  7.     To compile:
  8.     lc1 echo
  9.     lc2 -v echo
  10.  
  11.     To link:
  12.     alink with echo.with
  13.         or
  14.     blink with echo.with
  15. */
  16.  
  17. #include "exec/types.h"
  18. #include "exec/exec.h"
  19. #include "intuition/intuition.h"
  20. #include "soundscape.h"
  21.  
  22. /*    This is the definition of the state structure for this module.
  23.     It allows other programs to access these two parameters.
  24.     This is primarily for environment loads and saves.
  25. */
  26.  
  27. struct EchoState {
  28.     long length;
  29.     long delaytime;
  30.     long delaycount;
  31. };
  32.  
  33. struct EchoState echostate = { sizeof(echostate) - 4,24,4 };
  34. struct Note *notelist = 0;
  35. unsigned short thisport;
  36.  
  37. /*     Here's the image for the icon. */
  38.  
  39. UWORD echodata[] = {    /* 44 x 10 */ 
  40. 0,    0,    0,    
  41. 0,    0,    0,    
  42. 24,    0,    0,    
  43. 6,    0,    0,    
  44. 255,    32768,    0,    
  45. 6,    0,    0,    
  46. 24,    0,    0,    
  47. 0,    0,    0,    
  48. 0,    0,    0,    
  49. 0,    0,    0,    
  50. 0,    0,    0,    
  51. 6144,    768,    49200,    
  52. 6144,    768,    49200,    
  53. 6144,    768,    49200,    
  54. 6144,    768,    49200,    
  55. 6144,    768,    49200,    
  56. 63488,    7943,    49648,    
  57. 63488,    7943,    49648,    
  58. 0,    0,    0,    
  59. 0,    0,    0,    
  60. };
  61.  
  62. struct Image echoimage = { 0,0,44,10,2,echodata,3,0,0 };
  63.  
  64. /*    These are the Intuition structures for the user edit window.
  65.     These were generated with Power Windows. 
  66. */
  67.  
  68. UBYTE SIBuffer6[16] =
  69.     "24";
  70. struct StringInfo GadgetSI6 = {
  71.     SIBuffer6,
  72.     NULL,
  73.     0,
  74.     16,
  75.     0,
  76.     0,0,0,0,0,
  77.     0,
  78.     24,
  79.     NULL
  80. };
  81.  
  82. USHORT BorderVectors1[] = {0,0,111,0,111,9,0,9,0,0};
  83. struct Border Border1 = {
  84.     -2,-1,
  85.     1,0,JAM1,
  86.     5,
  87.     BorderVectors1,
  88.     NULL
  89. };
  90.  
  91. struct IntuiText IText1 = {
  92.     2,0,JAM2,
  93.     -109,0,
  94.     NULL,
  95.     "Delay Time",
  96.     NULL
  97. };
  98.  
  99. struct Gadget timegadget = {
  100.     NULL,
  101.     141,17,
  102.     108,8,
  103.     GADGHCOMP,
  104.     LONGINT+RELVERIFY+STRINGCENTER,
  105.     STRGADGET,
  106.     (APTR)&Border1,
  107.     NULL,
  108.     &IText1,
  109.     0,
  110.     (APTR)&GadgetSI6,
  111.     6,
  112.     NULL
  113. };
  114.  
  115. UBYTE SIBuffer5[16] =
  116.     "4";
  117. struct StringInfo GadgetSI5 = {
  118.     SIBuffer5,
  119.     NULL,
  120.     0,
  121.     16,
  122.     0,
  123.     0,0,0,0,0,
  124.     0,
  125.     4,
  126.     NULL
  127. };
  128.  
  129. USHORT BorderVectors2[] = {0,0,111,0,111,9,0,9,0,0};
  130. struct Border Border2 = {
  131.     -2,-1,
  132.     1,0,JAM1,
  133.     5,
  134.     BorderVectors2,
  135.     NULL
  136. };
  137.  
  138. struct IntuiText IText2 = {
  139.     2,0,JAM2,
  140.     -109,0,
  141.     NULL,
  142.     "Delay Count",
  143.     NULL
  144. };
  145.  
  146. struct Gadget countgadget = {
  147.     &timegadget,
  148.     141,32,
  149.     108,8,
  150.     GADGHCOMP,
  151.     LONGINT+RELVERIFY+STRINGCENTER,
  152.     STRGADGET,
  153.     (APTR)&Border2,
  154.     NULL,
  155.     &IText2,
  156.     0,
  157.     (APTR)&GadgetSI5,
  158.     5,
  159.     NULL
  160. };
  161.  
  162.  
  163. struct NewWindow NewWindowStructure = {
  164.     131,34,
  165.     286,51,
  166.     0,1,
  167.     GADGETUP+CLOSEWINDOW+RAWKEY,
  168.     WINDOWSIZING+WINDOWDRAG+WINDOWDEPTH+WINDOWCLOSE,
  169.     &countgadget,
  170.     NULL,
  171.     "Runtime Quantization",
  172.     NULL,
  173.     NULL,
  174.     5,5,
  175.     640,200,
  176.     WBENCHSCREEN
  177. };
  178.  
  179.  
  180. opencode(direction)
  181.  
  182. /*    Always happy to open. */
  183.  
  184. unsigned char direction;
  185.  
  186. {
  187.     return(1);
  188. }
  189.  
  190. closecode(direction)
  191.  
  192. /*    When closing down, throw out notelist. */
  193.  
  194. unsigned char direction;
  195.  
  196. {
  197.     struct Note *next;
  198.     for (;notelist;notelist = next) {
  199.     next = (struct Note *) notelist->link.next;
  200.     notelist->velocity = 0;     /* Force to off event. */
  201.     Send(thisport,notelist);
  202.     }
  203.     return(1);
  204. }
  205.  
  206. outcode(event)
  207.  
  208. struct Note *event;
  209.  
  210. {
  211.     static char running = 0;
  212.     struct Note *last, *note, *copy, *next;
  213.     unsigned short velocity;
  214.     switch (event->status) {
  215.     case START :
  216.     case CONTINUE :
  217.         running = 1;
  218.         break;
  219.     case STOP :
  220.         running = 0;
  221.         for (;notelist;notelist = next) {
  222.         next = (struct Note *) notelist->link.next;
  223.         notelist->velocity = 0;
  224.         Send(thisport,notelist);
  225.         }
  226.         break;
  227.     case CLOCK :
  228.         if (!running) break;
  229.         last = 0;
  230.         for (note = notelist; note; note = next) {
  231.         note->duration--;
  232.         next = (struct Note *) note->link.next;
  233.         if (!note->duration) {
  234.             copy = (struct Note *) AllocNode(NOTE);
  235.             if (copy) {
  236.             copy->status = note->status;
  237.             copy->value = note->value;
  238.             velocity = (note->velocity * note->wait) /
  239.                 echostate.delaycount;
  240.             copy->velocity = velocity;
  241.             Send(thisport,copy);
  242.             }
  243.             note->duration = echostate.delaytime;
  244.             note->wait--;
  245.             if (!note->wait) {
  246.             if (last) last->link.next = note->link.next;
  247.             else notelist = (struct Note *) note->link.next;
  248.             FreeNode(note);
  249.             }
  250.             else last = note;
  251.         }
  252.         else last = note;
  253.         }
  254.         break;
  255.     }
  256.     if (running && echostate.delaycount &&
  257.       (((event->status & 0xF0) == NOTEON) || 
  258.       ((event->status & 0xF0) == NOTEOFF))) {
  259.     event->link.next = (struct Link *) notelist;
  260.     notelist = event;
  261.     event->duration = echostate.delaytime;
  262.     event->wait = echostate.delaycount;
  263.     }
  264.     else FreeNode(event);
  265. }
  266.  
  267. useredit()
  268.  
  269. /*    Open a window with two string gadgets.  Wait for intuition
  270.     messages.
  271.     If CLOSEWINDOW, close down and return.
  272.     If RAWKEY, send the keycode to OutConsole.  This is a SoundScape
  273.     routine that will pass the key value to the Console Keyboard,
  274.     so it can be played from this window.
  275.     If GADGETUP, read the appropriate string gadget.
  276. */
  277.  
  278. {
  279.     struct IntuiMessage *message;
  280.     short code, class;
  281.     struct Gadget *gadget;
  282.     struct Window *window;
  283.     GadgetSI5.LongInt = echostate.delaycount;
  284.     GadgetSI6.LongInt = echostate.delaytime;
  285.     window = (struct Window *) OpenWindow(&NewWindowStructure);
  286.     for (;;) {
  287.     while (!(message = GetMsg(window->UserPort)))
  288.         WaitPort(window->UserPort);
  289.     class = message->Class;
  290.     code = message->Code;
  291.     gadget = (struct Gadget *) message->IAddress;
  292.     ReplyMsg(message);
  293.     if (class == CLOSEWINDOW) break;
  294.     if (class == RAWKEY) OutConsole(code);
  295.     if (class == GADGETUP) {
  296.         switch (gadget->GadgetID) {
  297.         case 5 :
  298.             echostate.delaycount = GadgetSI5.LongInt;
  299.             break;
  300.         case 6 :
  301.             echostate.delaytime = GadgetSI6.LongInt;
  302.             break;
  303.         }
  304.     }
  305.     }
  306.     CloseWindow(window);
  307. }
  308.  
  309. editcode(direction,command,copystate)
  310.  
  311. /*    This is the edit routine.  If the command is USEREDIT, call the
  312.     routine useredit which puts up a window and gadgets and lets the
  313.     user edit the two variables.  The variable notediting is
  314.     used to avoid begin invoked multiple times.
  315.     If GETSTATE or SAVESTATE, copy the echostate into the supplied buffer,
  316.     copystate.
  317.     For SETSTATE and LOADSTATE, do the reverse.
  318. */
  319.  
  320. char direction, command;
  321. struct EchoState *copystate;
  322.  
  323. {
  324.     static char notediting = 1;
  325.     echostate.length = sizeof(echostate) - 4;
  326.     switch (command) {
  327.     case USEREDIT :
  328.         if (notediting) {
  329.         notediting = 0;
  330.         useredit();
  331.         notediting = 1;
  332.         }
  333.         break;
  334.     case GETSTATE :
  335.     case SAVESTATE :
  336.         movmem(&echostate,copystate,sizeof(echostate));
  337.         break;
  338.     case SETSTATE :
  339.     case LOADSTATE :
  340.         movmem(copystate,&echostate,sizeof(echostate));
  341.         break;
  342.     }
  343. }
  344.         
  345. long SoundScapeBase;
  346. long IntuitionBase;
  347.  
  348. main() {
  349.     SoundScapeBase = OpenLibrary("soundscape.library",0);
  350.     if (SoundScapeBase) {
  351.     notelist = 0;
  352.     IntuitionBase = OpenLibrary("intuition.library",0);
  353.     CloseLibrary(SoundScapeBase);
  354.     thisport = AddMidiPort(opencode,closecode,editcode,outcode,&echoimage,
  355.         &echoimage,32,"echo");    
  356.     SetTaskPri(FindTask(0),-20);
  357.     while (MidiPort(thisport)) Delay(100);
  358.     CloseLibrary(IntuitionBase);
  359.     }
  360. }
  361.